package com.apes.scm.statement.customerConsignStatement.service;

import com.apes.framework.api.DomainService;
import com.apes.framework.api.SpringManager;
import com.apes.framework.jpa.generator.service.SequenceService;
import com.apes.framework.plugin.esb.api.SimpleRequest;
import com.apes.scm.account.account.model.InventoryConsign;
import com.apes.scm.account.account.model.InventoryMode;
import com.apes.scm.statement.customerConsignStatement.model.CustomerConsignStatement;
import com.apes.scm.statement.customerConsignStatement.repository.CustomerConsignStatementItemRepository;
import com.apes.scm.statement.customerConsignStatement.repository.CustomerConsignStatementRepository;
import com.apes.scm.voucher.model.Voucher;
import com.apes.scm.voucher.model.VoucherItem;
import com.apes.scm.voucher.service.BusinessType;
import com.apes.scm.voucher.service.VoucherService;
import com.apes.scm.voucher.service.VoucherType;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.Date;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;


@Service("customerConsignStatementService")
public class CustomerConsignStatementService extends DomainService {

    @Autowired
    CustomerConsignStatementRepository customerConsignStatementRepository;

    @Autowired
    CustomerConsignStatementItemRepository customerConsignStatementItemRepository;


    /*
    * 新增订单
    * */
    public CustomerConsignStatement create(SimpleRequest simpleRequest) {
        CustomerConsignStatement customerConsignStatement = simpleRequest.getO(CustomerConsignStatement.class);
        String id = SpringManager.getBean(SequenceService.class).getId(CustomerConsignStatement.CONST_TABLE_NAME);
        customerConsignStatement.setId(id);
        customerConsignStatement.setCreator(simpleRequest.getPersonId());
        return save(customerConsignStatement);
    }


    /*
    * 保存订单
    * */
    public CustomerConsignStatement save(CustomerConsignStatement customerConsignStatement) {
        customerConsignStatement.setState("sent");
        // 计算总金额, 明细设置id
        customerConsignStatement.computeAmtAndSetItemsId();

        // 增加寄售批次冻结数量
        changeCustomerConsignFrostQty(customerConsignStatement,true);

        return createCustomerConsignStatement(customerConsignStatement);
    }


    /*
    * 更新订单
    * */
    public CustomerConsignStatement update(SimpleRequest simpleRequest) {
        restore(simpleRequest);
        CustomerConsignStatement customerConsignStatement = simpleRequest.getO(CustomerConsignStatement.class);
        return save(customerConsignStatement);
    }


    /*
    * 删除订单
    * */
    public String delete(SimpleRequest simpleRequest) {
        CustomerConsignStatement customerConsignStatement = restore(simpleRequest);
        customerConsignStatementRepository.delete(customerConsignStatement);
        return "删除成功！";
    }



    /*
    * 恢复新增逻辑
    * */
    public CustomerConsignStatement restore(SimpleRequest simpleRequest) {
        CustomerConsignStatement customerConsignStatement = findValidCustomerConsignStatement(simpleRequest);
        // 减少寄售批次冻结数量
        changeCustomerConsignFrostQty(customerConsignStatement,false);
        return customerConsignStatement;
    }


    /*
    * 审核
    * */
    public CustomerConsignStatement approve(SimpleRequest simpleRequest) {
        CustomerConsignStatement customerConsignStatement = findValidCustomerConsignStatement(simpleRequest);
        customerConsignStatement.setState("approve");
        customerConsignStatement.setApproveDate(new Date());
        customerConsignStatement.setApproveUID(simpleRequest.getPerson());
        createConsignVoucher(customerConsignStatement);
        return customerConsignStatementRepository.saveAndFlush(customerConsignStatement);
    }

    /*
    * 创建寄售消耗/退回凭证
    * */
    public void createConsignVoucher(CustomerConsignStatement customerConsignStatement) {
        Voucher consignVoucher = new Voucher();
        consignVoucher.setCreator(customerConsignStatement.getApproveUID().getId());
        consignVoucher.setCompany(customerConsignStatement.getCompany());
        consignVoucher.setPartner(customerConsignStatement.getCustomer());
        consignVoucher.setVoucherType(VoucherType.CUSTOMER_CONSUME);
        consignVoucher.setInventoryMode(InventoryMode.IM_OWN);
        consignVoucher.setAccountingMethod(customerConsignStatement.getCooperation().getAccountingMethod());
        consignVoucher.setDept(customerConsignStatement.getDept());
        consignVoucher.setSource(customerConsignStatement.getId());
        consignVoucher.setSourceBusinessType(customerConsignStatement.getInnerBusinessType());
        consignVoucher.setOrigin(customerConsignStatement.getId());
        consignVoucher.setOriginBusinessType(customerConsignStatement.getInnerBusinessType());
        boolean isReturn = customerConsignStatement.isReturned();
        consignVoucher.setReturned(isReturn);
        consignVoucher.setBusinessType(isReturn ? BusinessType.CUSTOMER_CONSUME_RETURN_VOUCHER : BusinessType.CUSTOMER_CONSUME_ORDER_VOUCHER);
        consignVoucher.setVoucherItems(customerConsignStatement.getCustomerConsignStatementItems().stream().map(item -> {
                    VoucherItem voucherItem = new VoucherItem();
                    voucherItem.setInventoryConsign(item.getInventoryConsign());
                    voucherItem.setProduct(item.getProduct());
                    voucherItem.setTax(item.getTax());
                    voucherItem.setUom(item.getUom());
                    voucherItem.setPriceUnit(item.getPriceUnit());
                    voucherItem.setProductQty(isReturn ? -1 * item.getStatementQty():item.getStatementQty());
                    voucherItem.setOriginItemId(item.getId());
                    voucherItem.setSourceItemId(item.getId());
                    voucherItem.setVoucher(consignVoucher);
                    return voucherItem;
                }).collect(Collectors.toSet())
        );
        SpringManager.getBean(VoucherService.class).save(consignVoucher);
    }




    /*
    * 冻结/恢复 寄售批次冻结数量
    * 消耗：结存冻结数量； 退回：消耗冻结数量
    * */
    public void changeCustomerConsignFrostQty(CustomerConsignStatement customerConsignStatement,boolean isAdd) {
        int sign = isAdd ? 1 : 0;
        boolean isReturn = customerConsignStatement.isReturned();
        customerConsignStatement.getCustomerConsignStatementItems().forEach(
                (item) -> {
                    InventoryConsign inventoryConsign = item.getInventoryConsign();
                    if(inventoryConsign != null) {
                        if(isReturn) {
                            inventoryConsign.changeFrostConsumeQty(sign * item.getStatementQty());
                        }else {
                            inventoryConsign.changeFrostBalanceQty(sign *  item.getStatementQty());
                        }
                    }
                }
        );
    }


    /*
    * 查找有效对账订单
    * */
    public CustomerConsignStatement findValidCustomerConsignStatement(SimpleRequest simpleRequest) {
        CustomerConsignStatement customerConsignStatement = customerConsignStatementRepository.findOne((String)simpleRequest.get("id"));
        if(customerConsignStatement == null) throw new RuntimeException("客户寄售对账单不存在：" + (String)simpleRequest.get("id"));
        if(customerConsignStatement.getVersion() != (int)simpleRequest.get("version")) throw new RuntimeException("账单状态已改变,请重新查询订单！");
        return customerConsignStatement;
    }


    /*
    * 新增对账订单
    * */
    public CustomerConsignStatement createCustomerConsignStatement(CustomerConsignStatement customerConsignStatement) {
        return customerConsignStatementRepository.saveAndFlush(customerConsignStatement);
    }

    public List<Map<String,Object>> findItemsByStatementId(SimpleRequest simpleRequest) {
        String statementId = simpleRequest.get("statementId");
        return customerConsignStatementItemRepository.findAllByCustomerConsignStatementId(statementId);
    }

}
